﻿using System.Text;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace D.UtilCore.WChartUtils
{
    public static class WeChartEnterpriseUtil
    {
        public static string WeChatUrl = "https://qyapi.weixin.qq.com/cgi-bin/";
        public static string WeChartHttpClient = "WeChartEnterpriseClient";

        public static void AddWeChartEnterpriseUtil(this IServiceCollection services)
        {
            services.AddHttpClient(WeChartHttpClient, config =>
            {
                config.BaseAddress = new Uri(WeChatUrl);
                config.DefaultRequestHeaders.Add("Accept", "application/json");
            });
        }

        public static void UseWeChartEnterpriseUtil(this IApplicationBuilder app)
        {
            WeChartEnterpriseUtil.HttpClientFactory = app.ApplicationServices.GetService<IHttpClientFactory>();
        }

        public static IHttpClientFactory HttpClientFactory { get; set; }

        /// <summary>
        /// 过期时间
        /// </summary>
        public static DateTime TimeOutDate { get; set; }

        /// <summary>
        /// Token
        /// </summary>
        public static string Token { get; set; }

        /// <summary>
        /// 获取Token
        /// </summary>
        /// <returns>Item1 Token;Item2 是否成功</returns>
        public static Tuple<string, bool> GetToken(string corpid, string corpsecret)
        {
            Console.WriteLine("GetToken");
            //判断Token是否存在 以及Token是否在有效期内
            //if (string.IsNullOrEmpty(Token) || TimeOutDate > DateTime.Now)
            //{
                //构造请求链接
                var requestBuild = $"gettoken?corpid={corpid}&corpsecret={corpsecret}";

                using (var wxClient = HttpClientFactory.CreateClient(WeChartHttpClient))
                {
                    var httpResponse = wxClient.GetAsync(requestBuild).Result;
                    var dynamic = JsonConvert.DeserializeObject<WeChartToken>(httpResponse.Content.ReadAsStringAsync().Result);
                    if (dynamic.errcode == 0)
                    {
                        Token = dynamic.access_token;
                        // 过期5分钟前刷新Token
                        //var expires_in = Convert.ToDouble(dynamic.expires_in - 5 * 60);
                        //TimeOutDate = DateTime.Now.AddSeconds(110);
                        Console.WriteLine($"获取Token成功：{dynamic.access_token}");
                        //Console.WriteLine($"Token过期时间为：{TimeOutDate.ToString("yyyy-MM-dd HH:mm:ss:fff")}");
                        return Tuple.Create(dynamic.access_token, true);
                    }
                    else
                    {
                        return Tuple.Create($"获取Token失败，错误：{dynamic.errmsg}", false);
                    }
                }
            //}
            //else
            //{
            //    Console.WriteLine($"当前时间为：{TimeOutDate.ToString("yyyy-MM-dd HH:mm:ss:fff")}");
            //    Console.WriteLine($"Token过期时间为：{TimeOutDate.ToString("yyyy-MM-dd HH:mm:ss:fff")}");
            //    return Tuple.Create(Token, true);
            //}
        }

        /// <summary>
        /// 推送企业微信消息通知
        /// </summary>
        /// <returns>Item1 Token;Item2 是否成功</returns>
        public static string WxPush(string corpid, string corpsecret, string content)
        {
            Console.WriteLine($"执行WxPush，消息内容为：{content}");
            //构造请求链接
            var requestBuild = "message/send?access_token={0}";
            var (token, issuccess) = GetToken(corpid, corpsecret);
            if (!issuccess)
                throw new Exception(token);
            requestBuild = string.Format(requestBuild, token);
            //建立HttpClient
            using (var wxClient = HttpClientFactory.CreateClient(WeChartHttpClient))
            {
                byte[] data = Encoding.UTF8.GetBytes(content);
                var bytearray = new ByteArrayContent(data);
                var httpResponse = wxClient.PostAsync(requestBuild, bytearray).Result;
                var dynamic = JsonConvert.DeserializeObject<dynamic>(
                                     httpResponse.Content.ReadAsStringAsync().Result
                                     );
                if (dynamic.errcode == 0)
                    return "推送成功！";
                else
                    throw new Exception($"推送失败,原因:{JsonConvert.SerializeObject(dynamic)}");
            }
        }

        /// <summary>
        /// 获取发送内容
        /// </summary>
        /// <param name="agentid">应用ID</param>
        /// <param name="msg">消息内容</param>
        /// <param name="userId">用户ID，如果是@all则通知所有人，多个接收者用‘|’分隔，最多支持1000个</param>
        /// <returns></returns>
        public static string GetContent(string agentid, string msg, string userId = "@all")
        {
            Console.WriteLine($"企业微信消息发送给{userId}");
            var objText = new { content = msg };
            string text = JsonConvert.SerializeObject(objText);
            var obj = new
            {
                touser = userId,
                toparty = "",
                totag = "",
                msgtype = "text",
                agentid = agentid,
                text = objText,
                safe = 0,
                enable_id_trans = 0,
                enable_duplicate_check = 0,
                duplicate_check_interval = 1800
            };
            return JsonConvert.SerializeObject(obj);
        }

        #region 获取企业微信用户的userid
        /// <summary>
        /// 根据手机号获取Userid
        /// </summary>
        /// <param name="corpid"></param>
        /// <param name="corpsecret"></param>
        /// <param name="phone"></param>
        /// <param name="accessToken"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public static async Task<Tuple<string, bool>> GetUserIdByPhone(string corpid, string corpsecret, string phone)
        {
            //构造请求链接
            var requestBuild = "message/send?access_token={0}";
            var (token, issuccess) = GetToken(corpid, corpsecret);
            if (!issuccess)
                throw new Exception(token);
            requestBuild = string.Format(requestBuild, token);

            //构造请求链接
            var url = $"user/getuserid?access_token={token}";

            var content = new JObject();
            content.Add("mobile", phone);
            using (var wxClient = HttpClientFactory.CreateClient(WeChartHttpClient))
            {
                var httpResponse = await wxClient.PostAsync(url, new StringContent(content.ToString()));
                var result = await httpResponse.Content.ReadAsStringAsync();

                var dynamic = JsonConvert.DeserializeObject<WeChartUserId>(result);
                if (dynamic.errcode == 0)
                {
                    return Tuple.Create(dynamic.userid, true);
                }
                else
                {
                    return Tuple.Create($"获取{phone}的UserId失败，错误：{dynamic.errmsg}", false);
                }
            }
        }
        #endregion
    }
}
